/**
 * @fileoverview 閻ф儳瀹抽崷鏉挎禈閻ㄥ嫰绱堕弽鍥╃帛閸掕泛浼愰崗鍑ょ礉鐎电懓顦诲鈧弨淇扁偓锟
 * 閸忎浇顔忛悽銊﹀煕閸︺劌婀撮崶鍙ョ瑐閻愮懓鍤瑰本鍨氭Η鐘崇垼缂佹ê鍩楅惃鍕閼冲鈧拷
 * 娴ｈ法鏁ら懓鍛讲娴犮儴鍤滅规矮绠熼幍鈧紒妯哄煑缂佹挻鐏夐惃鍕祲閸忚櫕鐗卞蹇ョ礉娓氬顩х痪鍨啍閵嗕線顤侀懝灞傗偓浣圭ゴ缁炬寧顔岀捄婵堫瀲閵嗕線娼扮粔顖滅搼缁涘鈧拷
 * 娑撹鍙嗛崣锝囪閺勶拷<a href="symbols/BMapLib.DrawingManager.html">DrawingManager</a>閿涳拷
 * 閸╄桨绨珺aidu Map API 1.4閵嗭拷
 *
 * @author Baidu Map Api Group 
 * @version 1.4
 */

/** 
 * @namespace BMap閻ㄥ嫭澧嶉張濉磇brary缁娼庨弨鎯ф躬BMapLib閸涜棄鎮曠粚娲？娑擄拷
 */
var BMapLib = window.BMapLib = BMapLib || {};

/**
 * 鐎规矮绠熺敮鎼佸櫤, 缂佹ê鍩楅惃鍕佸锟
 * @final {Number} DrawingType
 */
var BMAP_DRAWING_MARKER    = "marker",     // 姒х姵鐖ｉ悽鑽ゅ仯濡崇础
    BMAP_DRAWING_POLYLINE  = "polyline",   // 姒х姵鐖ｉ悽鑽ゅ殠濡崇础
    BMAP_DRAWING_CIRCLE    = "circle",     // 姒х姵鐖ｉ悽璇叉妇濡崇础
    BMAP_DRAWING_RECTANGLE = "rectangle",  // 姒х姵鐖ｉ悽鑽ょ叐瑜般垺膩瀵拷
    BMAP_DRAWING_POLYGON   = "polygon";    // 姒х姵鐖ｉ悽璇差樋鏉堢懓鑸板Ο鈥崇础

(function() {

    /**
     * 婢圭増妲慴aidu閸栵拷
     */
    var baidu = baidu || {guid : "$BAIDU$"};
    (function() {
        // 娑撯偓娴滄盯銆夐棃銏㈤獓閸掝偄鏁稉鈧惃鍕潣閹嶇礉闂団偓鐟曚焦瀵曟潪钘夋躬window[baidu.guid]娑擄拷
        window[baidu.guid] = {};

        /**
         * 鐏忓棙绨电钖勯惃鍕閺堝鐫橀幀褎瀚圭拹婵嗗煂閻╊喗鐖ｇ电钖勬稉锟
         * @name baidu.extend
         * @function
         * @grammar baidu.extend(target, source)
         * @param {Object} target 閻╊喗鐖ｇ电钖
         * @param {Object} source 濠ф劕顕挒锟
         * @returns {Object} 閻╊喗鐖ｇ电钖
         */
        baidu.extend = function (target, source) {
            for (var p in source) {
                if (source.hasOwnProperty(p)) {
                    target[p] = source[p];
                }
            }    
            return target;
        };

        /**
         * @ignore
         * @namespace
         * @baidu.lang 鐎电顕㈢懛鈧仦鍌炴桨閻ㄥ嫬鐨濈憗鍜冪礉閸栧懏瀚猾璇茬烽崚銈嗘焽閵嗕焦膩閸ф澧跨仦鏇樷偓浣烘埛閹靛灝鐔缁浜掗崣濠傤嚠鐠灺ゅ殰鐎规矮绠熸禍瀣╂閻ㄥ嫭鏁幐浣碘偓锟
         * @property guid 鐎电钖勯惃鍕暜娑撯偓閺嶅洩鐦憇
         */
        baidu.lang = baidu.lang || {};

        /**
         * 鏉╂柨娲栨稉鈧稉顏勭秼閸撳秹銆夐棃銏㈡畱閸烆垯绔撮弽鍥槕鐎涙顑佹稉灞傗偓锟
         * @function
         * @grammar baidu.lang.guid()
         * @returns {String} 瑜版挸澧犳い鐢告桨閻ㄥ嫬鏁稉鈧弽鍥槕鐎涙顑佹稉锟
         */
        baidu.lang.guid = function() {
            return "TANGRAM__" + (window[baidu.guid]._counter ++).toString(36);
        };

        window[baidu.guid]._counter = window[baidu.guid]._counter || 1;

        /**
         * 閹碘偓閺堝琚惃鍕杽娓氬娈戠圭懓娅
         * key娑撶儤鐦℃稉顏勭杽娓氬娈慻uid
         */
        window[baidu.guid]._instances = window[baidu.guid]._instances || {};

        /**
         * Tangram缂佈勫閺堝搫鍩楅幓鎰返閻ㄥ嫪绔存稉顏勭唨缁紮绱濋悽銊﹀煕閸欘垯浜掗柅姘崇箖缂佈勫baidu.lang.Class閺夈儴骞忛崣鏍х暊閻ㄥ嫬鐫橀幀褍寮烽弬瑙勭《閵嗭拷
         * @function
         * @name baidu.lang.Class
         * @grammar baidu.lang.Class(guid)
         * @param {string} guid 鐎电钖勯惃鍕暜娑撯偓閺嶅洩鐦
         * @meta standard
         * @remark baidu.lang.Class閸滃苯鐣犻惃鍕摍缁崵娈戠圭偘绶ラ崸鍥у瘶閸氼偂绔存稉顏勫弿鐏炩偓閸烆垯绔撮惃鍕垼鐠囧攦uid閵嗭拷
         * guid閺勵垰婀弸鍕偓鐘插毐閺侀鑵戦悽鐔稿灇閻ㄥ嫸绱濋崶鐘愁劃閿涘瞼鎴烽幍鑳殰baidu.lang.Class閻ㄥ嫮琚惔鏃囶嚉閻╁瓨甯撮幋鏍偓鍛存？閹恒儴鐨熼悽銊ョ暊閻ㄥ嫭鐎柅鐘插毐閺佽埇鈧拷<br>
         * baidu.lang.Class閻ㄥ嫭鐎柅鐘插毐閺侀鑵戞禍褏鏁揼uid閻ㄥ嫭鏌熷蹇撳讲娴犮儰绻氱拠涔瑄id閻ㄥ嫬鏁稉鈧幀褝绱濋崣濠冪槨娑擃亜鐤勬笟瀣厴閺堝绔存稉顏勫弿鐏炩偓閸烆垯绔撮惃鍒id閵嗭拷
         */
        baidu.lang.Class = function(guid) {
            this.guid = guid || baidu.lang.guid();
            window[baidu.guid]._instances[this.guid] = this;
        };

        window[baidu.guid]._instances = window[baidu.guid]._instances || {};

        /**
         * 閸掋倖鏌囬惄顔界垼閸欏倹鏆熼弰顖氭儊string缁鐎烽幋鏈ring鐎电钖
         * @name baidu.lang.isString
         * @function
         * @grammar baidu.lang.isString(source)
         * @param {Any} source 閻╊喗鐖ｉ崣鍌涙殶
         * @shortcut isString
         * @meta standard
         *             
         * @returns {boolean} 缁鐎烽崚銈嗘焽缂佹挻鐏
         */
        baidu.lang.isString = function (source) {
            return '[object String]' == Object.prototype.toString.call(source);
        };

        /**
         * 閸掋倖鏌囬惄顔界垼閸欏倹鏆熼弰顖氭儊娑撶unction閹存湉unction鐎圭偘绶
         * @name baidu.lang.isFunction
         * @function
         * @grammar baidu.lang.isFunction(source)
         * @param {Any} source 閻╊喗鐖ｉ崣鍌涙殶
         * @returns {boolean} 缁鐎烽崚銈嗘焽缂佹挻鐏
         */
        baidu.lang.isFunction = function (source) {
            return '[object Function]' == Object.prototype.toString.call(source);
        };

        /**
         * 闁插秷娴囨禍鍡涚帛鐠併倗娈憈oString閺傝纭堕敍灞煎▏瀵版绻戦崶鐐颁繆閹垱娲块崝鐘插櫙绾喕绔存禍娑栤偓锟
         * @return {string} 鐎电钖勯惃鍑穞ring鐞涖劎銇氳ぐ銏犵础
         */
        baidu.lang.Class.prototype.toString = function(){
            return "[object " + (this._className || "Object" ) + "]";
        };

        /**
         * 闁插﹥鏂佺电钖勯幍鈧幐浣规箒閻ㄥ嫯绁┃鎰剁礉娑撴槒顩﹂弰顖濆殰鐎规矮绠熸禍瀣╂閵嗭拷
         * @name dispose
         * @grammar obj.dispose()
         */
        baidu.lang.Class.prototype.dispose = function(){
            delete window[baidu.guid]._instances[this.guid];
            for(var property in this){
                if (!baidu.lang.isFunction(this[property])) {
                    delete this[property];
                }
            }
            this.disposed = true;
        };

        /**
         * 閼奉亜鐣炬稊澶屾畱娴滃娆㈢电钖勯妴锟
         * @function
         * @name baidu.lang.Event
         * @grammar baidu.lang.Event(type[, target])
         * @param {string} type  娴滃娆㈢猾璇茬烽崥宥囆為妴鍌欒礋娴滃棙鏌熸笟鍨隘閸掑棔绨ㄦ禒璺烘嫲娑撯偓娑擃亝娅橀柅姘辨畱閺傝纭堕敍灞肩皑娴犲墎琚崹瀣倳缁夋澘绻妞よ浜"on"(鐏忓繐鍟)瀵偓婢舵番鈧拷
         * @param {Object} [target]鐟欙箑褰傛禍瀣╂閻ㄥ嫬顕挒锟
         * @meta standard
         * @remark 瀵洖鍙嗙拠銉δ侀崸妤嬬礉娴兼俺鍤滈崝銊よ礋Class瀵洖鍙3娑擃亙绨ㄦ禒鑸靛⒖鐏炴洘鏌熷▔鏇窗addEventListener閵嗕购emoveEventListener閸滃畳ispatchEvent閵嗭拷
         * @see baidu.lang.Class
         */
        baidu.lang.Event = function (type, target) {
            this.type = type;
            this.returnValue = true;
            this.target = target || null;
            this.currentTarget = null;
        };

        /**
         * 濞夈劌鍞界电钖勯惃鍕皑娴犲墎娲冮崥顒娅掗妴鍌氱穿閸忣櫒aidu.lang.Event閸氬函绱滳lass閻ㄥ嫬鐡欑猾璇茬杽娓氬澧犳导姘冲箯瀵版顕氶弬瑙勭《閵嗭拷
         * @grammar obj.addEventListener(type, handler[, key])
         * @param   {string}   type         閼奉亜鐣炬稊澶夌皑娴犲墎娈戦崥宥囆
         * @param   {Function} handler      閼奉亜鐣炬稊澶夌皑娴犳儼顫︾憴锕褰傞弮璺虹安鐠囥儴鐨熼悽銊ф畱閸ョ偠鐨熼崙鑺ユ殶
         * @param   {string}   [key]        娑撹桨绨ㄦ禒鍓佹磧閸氼剙鍤遍弫鐗堝瘹鐎规氨娈戦崥宥囆為敍灞藉讲閸︺劎些闂勩倖妞傛担璺ㄦ暏閵嗗倸顩ч弸婊绗夐幓鎰返閿涘本鏌熷▔鏇氱窗姒涙ǹ顓绘稉鍝勭暊閻㈢喐鍨氭稉鈧稉顏勫弿鐏炩偓閸烆垯绔撮惃鍒眅y閵嗭拷
         * @remark  娴滃娆㈢猾璇茬烽崠鍝勫瀻婢堆冪毈閸愭瑣鈧倸顩ч弸婊嗗殰鐎规矮绠熸禍瀣╂閸氬秶袨娑撳秵妲告禒銉ョ毈閸愶拷"on"瀵偓婢惰揪绱濈拠銉︽煙濞夋洑绱扮紒娆忕暊閸旂姳绗"on"閸愬秷绻樼悰灞藉灲閺傤叏绱濋崡锟"click"閸滐拷"onclick"娴兼俺顫︾拋銈勮礋閺勵垰鎮撴稉鈧粔宥勭皑娴犺翰鈧拷 
         */
        baidu.lang.Class.prototype.addEventListener = function (type, handler, key) {
            if (!baidu.lang.isFunction(handler)) {
                return;
            }
            !this.__listeners && (this.__listeners = {});
            var t = this.__listeners, id;
            if (typeof key == "string" && key) {
                if (/[^\w\-]/.test(key)) {
                    throw("nonstandard key:" + key);
                } else {
                    handler.hashCode = key; 
                    id = key;
                }
            }
            type.indexOf("on") != 0 && (type = "on" + type);
            typeof t[type] != "object" && (t[type] = {});
            id = id || baidu.lang.guid();
            handler.hashCode = id;
            t[type][id] = handler;
        };
         
        /**
         * 缁夊娅庣电钖勯惃鍕皑娴犲墎娲冮崥顒娅掗妴鍌氱穿閸忣櫒aidu.lang.Event閸氬函绱滳lass閻ㄥ嫬鐡欑猾璇茬杽娓氬澧犳导姘冲箯瀵版顕氶弬瑙勭《閵嗭拷
         * @grammar obj.removeEventListener(type, handler)
         * @param {string}   type     娴滃娆㈢猾璇茬
         * @param {Function|string} handler  鐟曚胶些闂勩倗娈戞禍瀣╂閻╂垵鎯夐崙鑺ユ殶閹存牞鈧懐娲冮崥顒鍤遍弫鎵畱key
         * @remark  婵″倹鐏夌粭顑跨癌娑擃亜寮弫鐧禷ndler濞屸剝婀佺悮顐ょ拨鐎规艾鍩岀电懓绨查惃鍕殰鐎规矮绠熸禍瀣╂娑擃叏绱濇禒鈧稊鍫滅瘍娑撳秴浠涢妴锟
         */
        baidu.lang.Class.prototype.removeEventListener = function (type, handler) {
            if (baidu.lang.isFunction(handler)) {
                handler = handler.hashCode;
            } else if (!baidu.lang.isString(handler)) {
                return;
            }
            !this.__listeners && (this.__listeners = {});
            type.indexOf("on") != 0 && (type = "on" + type);
            var t = this.__listeners;
            if (!t[type]) {
                return;
            }
            t[type][handler] && delete t[type][handler];
        };

        /**
         * 濞叉儳褰傞懛顏勭暰娑斿绨ㄦ禒璁圭礉娴ｅ灝绶辩紒鎴濈暰閸掓媽鍤滅规矮绠熸禍瀣╂娑撳﹪娼伴惃鍕毐閺佷即鍏樻导姘愁潶閹笛嗩攽閵嗗倸绱╅崗顧╝idu.lang.Event閸氬函绱滳lass閻ㄥ嫬鐡欑猾璇茬杽娓氬澧犳导姘冲箯瀵版顕氶弬瑙勭《閵嗭拷
         * @grammar obj.dispatchEvent(event, options)
         * @param {baidu.lang.Event|String} event   Event鐎电钖勯敍灞惧灗娴滃娆㈤崥宥囆(1.1.1鐠ч攱鏁幐锟)
         * @param {Object} options 閹碘晛鐫嶉崣鍌涙殶,閹碘偓閸氼偄鐫橀幀褔鏁崐闂寸窗閹碘晛鐫嶉崚鐧妚ent鐎电钖勬稉锟(1.2鐠ч攱鏁幐锟)
         * @remark 婢跺嫮鎮婃导姘崇殶閻€劑鈧俺绻僡ddEventListenr缂佹垵鐣鹃惃鍕殰鐎规矮绠熸禍瀣╂閸ョ偠鐨熼崙鑺ユ殶娑斿顦婚敍宀冪箷娴兼俺鐨熼悽銊ф纯閹恒儳绮︾规艾鍩岀电钖勬稉濠囨桨閻ㄥ嫯鍤滅规矮绠熸禍瀣╂閵嗭拷
         * 娓氬顩ч敍锟<br>
         * myobj.onMyEvent = function(){}<br>
         * myobj.addEventListener("onMyEvent", function(){});
         */
        baidu.lang.Class.prototype.dispatchEvent = function (event, options) {
            if (baidu.lang.isString(event)) {
                event = new baidu.lang.Event(event);
            }
            !this.__listeners && (this.__listeners = {});
            options = options || {};
            for (var i in options) {
                event[i] = options[i];
            }
            var i, t = this.__listeners, p = event.type;
            event.target = event.target || this;
            event.currentTarget = this;
            p.indexOf("on") != 0 && (p = "on" + p);
            baidu.lang.isFunction(this[p]) && this[p].apply(this, arguments);
            if (typeof t[p] == "object") {
                for (i in t[p]) {
                    t[p][i].apply(this, arguments);
                }
            }
            return event.returnValue;
        };

        /**
         * 娑撹櫣琚崹瀣柅鐘叉珤瀵よ櫣鐝涚紒褎澹欓崗宕囬兇
         * @name baidu.lang.inherits
         * @function
         * @grammar baidu.lang.inherits(subClass, superClass[, className])
         * @param {Function} subClass 鐎涙劗琚弸鍕偓鐘叉珤
         * @param {Function} superClass 閻栧墎琚弸鍕偓鐘叉珤
         * @param {string} className 缁鎮曢弽鍥槕
         * @remark 娴ｇ府ubClass缂佈勫superClass閻ㄥ埦rototype閿涳拷
         * 閸ョ姵顒漵ubClass閻ㄥ嫬鐤勬笟瀣厴婢剁喍濞囬悽鈺痷perClass閻ㄥ埦rototype娑擃厼鐣炬稊澶屾畱閹碘偓閺堝鐫橀幀褍鎷伴弬瑙勭《閵嗭拷<br>
         * 鏉╂瑤閲滈崙鑺ユ殶鐎圭偤妾稉濠冩Ц瀵よ櫣鐝涙禍鍞杣bClass閸滃uperClass閻ㄥ嫬甯崹瀣懠闂嗗棙鍨氶敍灞借嫙鐎电畟ubClass鏉╂稖顢戞禍鍝籵nstructor娣囶喗顒滈妴锟<br>
         * <strong>濞夈劍鍓伴敍姘洤閺嬫粏顩︾紒褎澹欓弸鍕偓鐘插毐閺佸府绱濋棁鈧憰浣告躬subClass闁插矂娼癱all娑撯偓娑撳绱濋崗铚傜秼鐟欎椒绗呴棃銏㈡畱demo娓氬鐡</strong>
         * @shortcut inherits
         * @meta standard
         * @see baidu.lang.Class
         */
        baidu.lang.inherits = function (subClass, superClass, className) {
            var key, proto, 
                selfProps = subClass.prototype, 
                clazz = new Function();        
            clazz.prototype = superClass.prototype;
            proto = subClass.prototype = new clazz();
            for (key in selfProps) {
                proto[key] = selfProps[key];
            }
            subClass.prototype.constructor = subClass;
            subClass.superClass = superClass.prototype;

            if ("string" == typeof className) {
                proto._className = className;
            }
        };

        /**
         * @ignore
         * @namespace baidu.dom 閹垮秳缍攄om閻ㄥ嫭鏌熷▔鏇樷偓锟
         */
        baidu.dom = baidu.dom || {};

        /**
         * 娴犲孩鏋冨锝勮厬閼惧嘲褰囬幐鍥х暰閻ㄥ嚍OM閸忓啰绀
         * 
         * @param {string|HTMLElement} id 閸忓啰绀岄惃鍒琩閹存湆OM閸忓啰绀
         * @meta standard
         * @return {HTMLElement} DOM閸忓啰绀岄敍灞筋洤閺嬫粈绗夌涙ê婀敍宀冪箲閸ョ梪ll閿涘苯顩ч弸婊冨棘閺侀绗夐崥鍫熺《閿涘瞼娲块幒銉ㄧ箲閸ョ偛寮弫锟
         */
        baidu._g = baidu.dom._g = function (id) {
            if (baidu.lang.isString(id)) {
                return document.getElementById(id);
            }
            return id;
        };

        /**
         * 娴犲孩鏋冨锝勮厬閼惧嘲褰囬幐鍥х暰閻ㄥ嚍OM閸忓啰绀
         * @name baidu.dom.g
         * @function
         * @grammar baidu.dom.g(id)
         * @param {string|HTMLElement} id 閸忓啰绀岄惃鍒琩閹存湆OM閸忓啰绀
         * @meta standard
         *             
         * @returns {HTMLElement|null} 閼惧嘲褰囬惃鍕帗缁辩媴绱濋弻銉﹀娑撳秴鍩岄弮鎯扮箲閸ョ梪ll,婵″倹鐏夐崣鍌涙殶娑撳秴鎮庡▔鏇礉閻╁瓨甯存潻鏂挎礀閸欏倹鏆
         */
        baidu.g = baidu.dom.g = function (id) {
            if ('string' == typeof id || id instanceof String) {
                return document.getElementById(id);
            } else if (id && id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {
                return id;
            }
            return null;
        };

        /**
         * 閸︺劎娲伴弽鍥у帗缁辩姷娈戦幐鍥х暰娴ｅ秶鐤嗛幓鎺戝弳HTML娴狅絿鐖
         * @name baidu.dom.insertHTML
         * @function
         * @grammar baidu.dom.insertHTML(element, position, html)
         * @param {HTMLElement|string} element 閻╊喗鐖ｉ崗鍐閹存牜娲伴弽鍥у帗缁辩姷娈慽d
         * @param {string} position 閹绘帒鍙唄tml閻ㄥ嫪缍呯純顔讳繆閹垽绱濋崣鏍р偓闂磋礋beforeBegin,afterBegin,beforeEnd,afterEnd
         * @param {string} html 鐟曚焦褰冮崗銉ф畱html
         * @remark
         * 
         * 鐎甸涚艾position閸欏倹鏆熼敍灞姐亣鐏忓繐鍟撴稉宥嗘櫛閹帮拷<br>
         * 閸欏倹鏆熼惃鍕壈閹繐绱癰eforeBegin&lt;span&gt;afterBegin   this is span! beforeEnd&lt;/span&gt; afterEnd <br />
         * 濮濄倕顦婚敍灞筋洤閺嬫粈濞囬悽銊︽拱閸戣姤鏆熼幓鎺戝弳鐢附婀乻cript閺嶅洨顒烽惃鍑ML鐎涙顑佹稉璇х礉script閺嶅洨顒风电懓绨查惃鍕壖閺堫剙鐨㈡稉宥勭窗鐞氼偅澧界悰灞烩偓锟
         * 
         * @shortcut insertHTML
         * @meta standard
         *             
         * @returns {HTMLElement} 閻╊喗鐖ｉ崗鍐
         */
        baidu.insertHTML = baidu.dom.insertHTML = function (element, position, html) {
            element = baidu.dom.g(element);
            var range,begin;

            if (element.insertAdjacentHTML) {
                element.insertAdjacentHTML(position, html);
            } else {
                // 鏉╂瑩鍣锋稉宥呬粵"undefined" != typeof(HTMLElement) && !window.opera閸掋倖鏌囬敍灞藉従鐎瑰啯绁荤憴鍫濇珤鐏忓棗鍤柨娆欑吹閿涳拷
                // 娴ｅ棙妲搁崗璺虹杽閸嬫矮绨￠崚銈嗘焽閿涘苯鍙剧瑰啯绁荤憴鍫濇珤娑撳鐡戞禍搴ょ箹娑擃亜鍤遍弫鏉挎皑娑撳秷鍏橀幍褑顢戞禍锟
                range = element.ownerDocument.createRange();
                // FF娑撳獰ange閻ㄥ嫪缍呯純顔款啎缂冾噣鏁婄拠顖氬讲閼宠棄顕遍懛鏉戝灡瀵ゅ搫鍤弶銉ф畱fragment閸︺劍褰冮崗顧猳m閺嶆垳绠ｉ崥宸媡ml缂佹挻鐎稊杈ㄥ竴
                // 閺鍦暏range.insertNode閺夈儲褰冮崗顧畉ml, by wenyuxiang @ 2010-12-14.
                position = position.toUpperCase();
                if (position == 'AFTERBEGIN' || position == 'BEFOREEND') {
                    range.selectNodeContents(element);
                    range.collapse(position == 'AFTERBEGIN');
                } else {
                    begin = position == 'BEFOREBEGIN';
                    range[begin ? 'setStartBefore' : 'setEndAfter'](element);
                    range.collapse(begin);
                }
                range.insertNode(range.createContextualFragment(html));
            }
            return element;
        };

        /**
         * 娑撹櫣娲伴弽鍥у帗缁辩姵鍧婇崝鐕緇assName
         * @name baidu.dom.addClass
         * @function
         * @grammar baidu.dom.addClass(element, className)
         * @param {HTMLElement|string} element 閻╊喗鐖ｉ崗鍐閹存牜娲伴弽鍥у帗缁辩姷娈慽d
         * @param {string} className 鐟曚焦鍧婇崝鐘垫畱className閿涘苯鍘戠拋绋挎倱閺冭埖鍧婇崝鐘差樋娑撶寶lass閿涘奔鑵戦梻缈犲▏閻€劎鈹栭惂鐣岊儊閸掑棝娈
         * @remark
         * 娴ｈ法鏁ら懓鍛安娣囨繆鐦夐幓鎰返閻ㄥ垻lassName閸氬牊纭堕幀褝绱濇稉宥呯安閸栧懎鎯堟稉宥呮値濞夋洖鐡х粭锔肩礉className閸氬牊纭剁涙顑侀崣鍌濃偓鍐跨窗http://www.w3.org/TR/CSS2/syndata.html閵嗭拷
         * @shortcut addClass
         * @meta standard
         *              
         * @returns {HTMLElement} 閻╊喗鐖ｉ崗鍐
         */
        baidu.ac = baidu.dom.addClass = function (element, className) {
            element = baidu.dom.g(element);
            var classArray = className.split(/\s+/),
                result = element.className,
                classMatch = " " + result + " ",
                i = 0,
                l = classArray.length;

            for (; i < l; i++){
                 if ( classMatch.indexOf( " " + classArray[i] + " " ) < 0 ) {
                     result += (result ? ' ' : '') + classArray[i];
                 }
            }

            element.className = result;
            return element;
        };

        /**
         * @ignore
         * @namespace baidu.event 鐏炲繗鏂濞村繗顫嶉崳銊ユ▕瀵倹鈧呮畱娴滃娆㈢亸浣筋棅閵嗭拷
         * @property target     娴滃娆㈤惃鍕曢崣鎴濆帗缁憋拷
         * @property pageX      姒х姵鐖ｆ禍瀣╂閻ㄥ嫰绱堕弽鍣氶崸鎰垼
         * @property pageY      姒х姵鐖ｆ禍瀣╂閻ㄥ嫰绱堕弽鍣涢崸鎰垼
         * @property keyCode    闁款喚娲忔禍瀣╂閻ㄥ嫰鏁崐锟
         */
        baidu.event = baidu.event || {};

        /**
         * 娴滃娆㈤惄鎴濇儔閸ｃ劎娈戠涙ê鍋嶇悰锟
         * @private
         * @meta standard
         */
        baidu.event._listeners = baidu.event._listeners || [];

        /**
         * 娑撹櫣娲伴弽鍥у帗缁辩姵鍧婇崝鐘辩皑娴犲墎娲冮崥顒娅
         * @name baidu.event.on
         * @function
         * @grammar baidu.event.on(element, type, listener)
         * @param {HTMLElement|string|window} element 閻╊喗鐖ｉ崗鍐閹存牜娲伴弽鍥у帗缁辩垊d
         * @param {string} type 娴滃娆㈢猾璇茬
         * @param {Function} listener 闂団偓鐟曚焦鍧婇崝鐘垫畱閻╂垵鎯夐崳锟
         * @remark
         *  1. 娑撳秵鏁幐浣芥硶濞村繗顫嶉崳銊ф畱姒х姵鐖ｅ⿰姘崇枂娴滃娆㈤惄鎴濇儔閸ｃ劍鍧婇崝锟<br>
         *  2. 閺瑙勬煙濞夋洑绗夋稉铏规磧閸氼剙娅掗悘灞藉弳娴滃娆㈢电钖勯敍灞间簰闂冨弶顒涚捄鈺rame娴滃娆㈤幐鍌濇祰閻ㄥ嫪绨ㄦ禒璺侯嚠鐠灺ゅ箯閸欐牕銇戠拹锟            
         * @shortcut on
         * @meta standard
         * @see baidu.event.un
         *             
         * @returns {HTMLElement|window} 閻╊喗鐖ｉ崗鍐
         */
        baidu.on = baidu.event.on = function (element, type, listener) {
            type = type.replace(/^on/i, '');
            element = baidu._g(element);
            var realListener = function (ev) {
                // 1. 鏉╂瑩鍣锋稉宥嗘暜閹镐笒ventArgument,  閸樼喎娲滈弰顖濇硶frame閻ㄥ嫪绨ㄦ禒鑸靛瘯鏉烇拷
                // 2. element閺勵垯璐熸禍鍡曟叏濮濐柡his
                listener.call(element, ev);
            },
            lis = baidu.event._listeners,
            filter = baidu.event._eventFilter,
            afterFilter,
            realType = type;
            type = type.toLowerCase();
            // filter鏉╁洦鎶
            if(filter && filter[type]){
                afterFilter = filter[type](element, type, realListener);
                realType = afterFilter.type;
                realListener = afterFilter.listener;
            }
            // 娴滃娆㈤惄鎴濇儔閸ｃ劍瀵曟潪锟
            if (element.addEventListener) {
                element.addEventListener(realType, realListener, false);
            } else if (element.attachEvent) {
                element.attachEvent('on' + realType, realListener);
            }
          
            // 鐏忓棛娲冮崥顒娅掔涙ê鍋嶉崚鐗堟殶缂佸嫪鑵
            lis[lis.length] = [element, type, listener, realListener, realType];
            return element;
        };

        /**
         * 娑撹櫣娲伴弽鍥у帗缁辩姷些闂勩倓绨ㄦ禒鍓佹磧閸氼剙娅
         * @name baidu.event.un
         * @function
         * @grammar baidu.event.un(element, type, listener)
         * @param {HTMLElement|string|window} element 閻╊喗鐖ｉ崗鍐閹存牜娲伴弽鍥у帗缁辩垊d
         * @param {string} type 娴滃娆㈢猾璇茬
         * @param {Function} listener 闂団偓鐟曚胶些闂勩倗娈戦惄鎴濇儔閸ｏ拷
         * @shortcut un
         * @meta standard
         *             
         * @returns {HTMLElement|window} 閻╊喗鐖ｉ崗鍐
         */
        baidu.un = baidu.event.un = function (element, type, listener) {
            element = baidu._g(element);
            type = type.replace(/^on/i, '').toLowerCase();
            
            var lis = baidu.event._listeners, 
                len = lis.length,
                isRemoveAll = !listener,
                item,
                realType, realListener;
            
            //婵″倹鐏夌亸鍞媔stener閻ㄥ嫮绮ㄩ弸鍕暭閹存亾son
            //閸欘垯浜掗懞鍌滄阜閹哄绻栨稉顏勬儕閻滎垽绱濇导妯哄閹嗗厴
            //娴ｅ棙妲搁悽鍙樼艾un閻ㄥ嫪濞囬悽銊╊暥閻滃洤鑻熸稉宥夌彯閿涘苯鎮撻弮璺烘躬listener娑撳秴顦块惃鍕閸婏拷
            //闁秴宸婚弫鎵矋閻ㄥ嫭鈧嗗厴濞戝牐鈧ぞ绗夋导姘嚠娴狅絿鐖滄禍褏鏁撹ぐ鍗炴惙
            //閺嗗倷绗夐懓鍐濮濄倓绱崠锟
            while (len--) {
                item = lis[len];
                
                // listener鐎涙ê婀弮璁圭礉缁夊娅巈lement閻ㄥ嫭澧嶉張澶変簰listener閻╂垵鎯夐惃鍓噛pe缁鐎锋禍瀣╂
                // listener娑撳秴鐡ㄩ崷銊︽閿涘瞼些闂勵構lement閻ㄥ嫭澧嶉張濉紋pe缁鐎锋禍瀣╂
                if (item[1] === type
                    && item[0] === element
                    && (isRemoveAll || item[2] === listener)) {
                    realType = item[4];
                    realListener = item[3];
                    if (element.removeEventListener) {
                        element.removeEventListener(realType, realListener, false);
                    } else if (element.detachEvent) {
                        element.detachEvent('on' + realType, realListener);
                    }
                    lis.splice(len, 1);
                }
            }            
            return element;
        };

        /**
         * 閼惧嘲褰噀vent娴滃娆,鐟欙絽鍠呮稉宥呮倱濞村繗顫嶉崳銊ュ悑鐎瑰綊妫舵０锟
         * @param {Event}
         * @return {Event}
         */
        baidu.getEvent = baidu.event.getEvent = function (event) {
            return window.event || event;
        }

        /**
         * 閼惧嘲褰噀vent.target,鐟欙絽鍠呮稉宥呮倱濞村繗顫嶉崳銊ュ悑鐎瑰綊妫舵０锟
         * @param {Event}
         * @return {Target}
         */
        baidu.getTarget = baidu.event.getTarget = function (event) {
            var event = baidu.getEvent(event);
            return event.target || event.srcElement;
        }

        /**
         * 闂冪粯顒涙禍瀣╂閻ㄥ嫰绮拋銈堫攽娑擄拷
         * @name baidu.event.preventDefault
         * @function
         * @grammar baidu.event.preventDefault(event)
         * @param {Event} event 娴滃娆㈢电钖
         * @meta standard
         */
        baidu.preventDefault = baidu.event.preventDefault = function (event) {
           var event = baidu.getEvent(event);
           if (event.preventDefault) {
               event.preventDefault();
           } else {
               event.returnValue = false;
           }
        };

        /**
         * 閸嬫粍顒涙禍瀣╂閸愭帗鍦烘导鐘虫尡
         * @param {Event}
         */
        baidu.stopBubble = baidu.event.stopBubble = function (event) {
            event = baidu.getEvent(event);
            event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
        }

        baidu.browser = baidu.browser || {};

            if (/msie (\d+\.\d)/i.test(navigator.userAgent)) {
                //IE 8娑撳绱濇禒顧猳cumentMode娑撳搫鍣
                //閸︺劎娅ㄦ惔锔侥侀弶澶歌厬閿涘苯褰查懗鎴掔窗閺堬拷$閿涘矂妲诲銏犲暱缁愪緤绱濈亸锟$1 閸愭瑦鍨 \x241
            /**
             * 閸掋倖鏌囬弰顖氭儊娑撶e濞村繗顫嶉崳锟
             * @property ie ie閻楀牊婀伴崣锟
             * @grammar baidu.browser.ie
             * @meta standard
             * @shortcut ie
             * @see baidu.browser.firefox,baidu.browser.safari,baidu.browser.opera,baidu.browser.chrome,baidu.browser.maxthon 
             */
               baidu.browser.ie = baidu.ie = document.documentMode || + RegExp['\x241'];
}

    })();

    /** 
     * @exports DrawingManager as BMapLib.DrawingManager 
     */
    var DrawingManager =
        /**
         * DrawingManager缁崵娈戦弸鍕偓鐘插毐閺侊拷
         * @class 姒х姵鐖ｇ紒妯哄煑缁狅紕鎮婄猾浼欑礉鐎圭偟骞囨Η鐘崇垼缂佹ê鍩楃粻锛勬倞閻拷<b>閸忋儱褰</b>閵嗭拷
         * 鐎圭偘绶ラ崠鏍嚉缁鎮楅敍灞藉祮閸欘垵鐨熼悽銊嚉缁粯褰佹笟娑氭畱open
         * 閺傝纭跺鈧崥顖滅帛閸掕埖膩瀵繒濮搁幀浣碘偓锟
         * 娑旂喎褰查崝鐘插弳瀹搞儱鍙块弽蹇氱箻鐞涘矂鈧瀚ㄩ幙宥勭稊閵嗭拷
         * 
         * @constructor
         * @param {Map} map Baidu map閻ㄥ嫬鐤勬笟瀣嚠鐠烇拷
         * @param {Json Object} opts 閸欘垶鈧娈戞潏鎾冲弳閸欏倹鏆熼敍宀勬姜韫囧懎锝炴い骞库偓鍌氬讲鏉堟挸鍙嗛柅澶愩嶉崠鍛閿涳拷<br />
         * {"<b>isOpen</b>" : {Boolean} 閺勵垰鎯佸鈧崥顖滅帛閸掕埖膩瀵拷
         * <br />"<b>enableDrawingTool</b>" : {Boolean} 閺勵垰鎯佸ǎ璇插缂佹ê鍩楀銉ュ徔閺嶅繑甯舵禒璁圭礉姒涙ǹ顓绘稉宥嗗潑閸旓拷
         * <br />"<b>drawingToolOptions</b>" : {Json Object} 閸欘垶鈧娈戞潏鎾冲弳閸欏倹鏆熼敍宀勬姜韫囧懎锝炴い骞库偓鍌氬讲鏉堟挸鍙嗛柅澶愩嶉崠鍛
         * <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"<b>anchor</b>" : {ControlAnchor} 閸嬫粓娼担宥囩枂閵嗕線绮拋銈呬箯娑撳﹨顫
         * <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"<b>offset</b>" : {Size} 閸嬪繒些閸婄鈧拷
         * <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"<b>scale</b>" : {Number} 瀹搞儱鍙块弽蹇曟畱缂傗晜鏂佸В鏂剧伐,姒涙ǹ顓绘稉锟1
         * <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"<b>drawingModes</b>" : {DrawingType<Array>} 瀹搞儱鍙块弽蹇庣瑐閸欘垯浜掗柅澶嬪閸戣櫣骞囬惃鍕帛閸掕埖膩瀵拷,鐏忓棝娓剁憰浣规▔缁铏规畱DrawingType娴犮儲鏆熺紒鍕疯ぐ銏犵础娴肩姴鍙嗛敍灞筋洤[BMAP_DRAWING_MARKER, BMAP_DRAWING_CIRCLE] 鐏忓棗褰ч弰鍓с仛閻㈣崵鍋ｉ崪宀鏁鹃崷鍡欐畱闁銆
         * <br />"<b>enableCalculate</b>" : {Boolean} 缂佹ê鍩楅弰顖氭儊鏉╂稖顢戝ù瀣獩(閻㈣崵鍤庨弮璺衡偓锟)閵嗕焦绁撮棃锟(閻㈣娓鹃妴浣割樋鏉堢懓鑸伴妴浣虹叐瑜帮拷)
         * <br />"<b>markerOptions</b>" : {CircleOptions} 閹碘偓閻㈣崵娈戦悙鍦畱閸欘垶鈧寮弫甯礉閸欏倽鈧儭pi娑擃厾娈<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">鐎电懓绨茬猾锟</a>
         * <br />"<b>circleOptions</b>" : {CircleOptions} 閹碘偓閻㈣崵娈戦崷鍡欐畱閸欘垶鈧寮弫甯礉閸欏倽鈧儭pi娑擃厾娈<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">鐎电懓绨茬猾锟</a>
         * <br />"<b>polylineOptions</b>" : {CircleOptions} 閹碘偓閻㈣崵娈戠痪璺ㄦ畱閸欘垶鈧寮弫甯礉閸欏倽鈧儭pi娑擃厾娈<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">鐎电懓绨茬猾锟</a>
         * <br />"<b>polygonOptions</b>" : {PolygonOptions} 閹碘偓閻㈣崵娈戞径姘崇珶瑜般垻娈戦崣顖炩偓澶婂棘閺佸府绱濋崣鍌濃偓鍍i娑擃厾娈<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">鐎电懓绨茬猾锟</a>
         * <br />"<b>rectangleOptions</b>" : {PolygonOptions} 閹碘偓閻㈣崵娈戦惌鈺佽埌閻ㄥ嫬褰查柅澶婂棘閺佸府绱濋崣鍌濃偓鍍i娑擃厾娈<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">鐎电懓绨茬猾锟</a>
         *
         * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b><br />
         * var map = new BMap.Map("container");<br />map.centerAndZoom(new BMap.Point(116.404, 39.915), 15);<br />
         * var myDrawingManagerObject = new BMapLib.DrawingManager(map, {isOpen: true, 
         *     drawingType: BMAP_DRAWING_MARKER, enableDrawingTool: true,
         *     enableCalculate: false,
         *     drawingToolOptions: {
         *         anchor: BMAP_ANCHOR_TOP_LEFT,
         *         offset: new BMap.Size(5, 5),
         *         drawingTypes : [
         *             BMAP_DRAWING_MARKER,
         *             BMAP_DRAWING_CIRCLE,
         *             BMAP_DRAWING_POLYLINE,
         *             BMAP_DRAWING_POLYGON,
         *             BMAP_DRAWING_RECTANGLE 
         *          ]
         *     },
         *     polylineOptions: {
         *         strokeColor: "#333"
         *     });
         */
        BMapLib.DrawingManager = function(map, opts){
            if (!map) {
                return;
            }
            instances.push(this);
            
            opts = opts || {};

            this._initialize(map, opts);
        }

    // 闁俺绻僢aidu.lang娑撳娈慽nherits閺傝纭堕敍宀冾唨DrawingManager缂佈勫baidu.lang.Class
    baidu.lang.inherits(DrawingManager, baidu.lang.Class, "DrawingManager");

    /**
     * 瀵偓閸氼垰婀撮崶鍓ф畱缂佹ê鍩楀Ο鈥崇础
     *
     * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b><br />
     * myDrawingManagerObject.open();
     */
    DrawingManager.prototype.open = function() {
        // 閸掋倖鏌囩紒妯哄煑閻樿埖鈧焦妲搁崥锕鍑＄紒蹇撶磻閸氾拷
        if (this._isOpen == true){
            return true;
        }
        closeInstanceExcept(this);

        this._open();
    }

    /**
     * 閸忔娊妫撮崷鏉挎禈閻ㄥ嫮绮崚鍓佸Ц閹拷
     *
     * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b><br />
     * myDrawingManagerObject.close();
     */
    DrawingManager.prototype.close = function() {

        // 閸掋倖鏌囩紒妯哄煑閻樿埖鈧焦妲搁崥锕鍑＄紒蹇撶磻閸氾拷
        if (this._isOpen == false){
            return true;
        }
        var me = this;
        this._close();
        setTimeout(function(){
            me._map.enableDoubleClickZoom();
        },2000);
        
    }

    /**
     * 鐠佸墽鐤嗚ぐ鎾冲閻ㄥ嫮绮崚鑸的佸蹇ョ礉閸欏倹鏆烡rawingType閿涘奔璐5娑擃亜褰查柅澶婄埗闁诧拷:
     * <br/>BMAP_DRAWING_MARKER    閻㈣崵鍋
     * <br/>BMAP_DRAWING_CIRCLE    閻㈣娓
     * <br/>BMAP_DRAWING_POLYLINE  閻㈣崵鍤
     * <br/>BMAP_DRAWING_POLYGON   閻㈣顦挎潏鐟拌埌
     * <br/>BMAP_DRAWING_RECTANGLE 閻㈣崵鐓╄ぐ锟
     * @param {DrawingType} DrawingType
     * @return {Boolean} 
     *
     * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b><br />
     * myDrawingManagerObject.setDrawingMode(BMAP_DRAWING_POLYLINE);
     */
    DrawingManager.prototype.setDrawingMode = function(drawingType) {
        //娑撳骸缍嬮崜宥喣佸蹇庣瑝娑撯偓閺嶉攱妞傞崐娆愬鏉╂稖顢戦柌宥嗘煀缂佹垵鐣炬禍瀣╂
        if (this._drawingType != drawingType) {
            closeInstanceExcept(this);
            this._setDrawingMode(drawingType);
        }
    }

    /**
     * 閼惧嘲褰囪ぐ鎾冲閻ㄥ嫮绮崚鑸的佸锟
     * @return {DrawingType} 缂佹ê鍩楅惃鍕佸锟
     *
     * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b><br />
     * alert(myDrawingManagerObject.getDrawingMode());
     */
    DrawingManager.prototype.getDrawingMode = function() {
        return this._drawingType;
    }

    /**
     * 閹垫挸绱戠捄婵堫瀲閹存牠娼扮粔顖濐吀缁狅拷
     *
     * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b><br />
     * myDrawingManagerObject.enableCalculate();
     */
    DrawingManager.prototype.enableCalculate = function() {
        this._enableCalculate = true;
        this._addGeoUtilsLibrary();
    }

    /**
     * 閸忔娊妫寸捄婵堫瀲閹存牠娼扮粔顖濐吀缁狅拷
     *
     * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b><br />
     * myDrawingManagerObject.disableCalculate();
     */
    DrawingManager.prototype.disableCalculate = function() {
        this._enableCalculate = false;
    }

    /**
     * 姒х姵鐖ｇ紒妯哄煑鐎瑰本鍨氶崥搴礉濞叉儳褰傞幀璁崇皑娴犲墎娈戦幒銉ュ經
     * @name DrawingManager#overlaycomplete
     * @event
     * @param {Event Object} e 閸ョ偠鐨熼崙鑺ユ殶娴兼俺绻戦崶鐎峷ent閸欏倹鏆熼敍灞藉瘶閹奉兛浜掓稉瀣箲閸ョ偛鈧》绱
     * <br />{"<b>drawingMode</b> : {DrawingType} 瑜版挸澧犻惃鍕帛閸掕埖膩瀵拷
     * <br />"<b>overlay</b>閿涙Marker||Polyline||Polygon||Circle} 鐎电懓绨查惃鍕帛閸掕埖膩瀵繗绻戦崶鐐差嚠鎼存梻娈戠憰鍡欐磰閻楋拷
     * <br />"<b>calculate</b>閿涙Number} 闂団偓鐟曚礁绱戦崥顖濐吀缁犳膩瀵繑澧犳导姘崇箲閸ョ偠绻栨稉顏勨偓纭风礉瑜版挾绮崚鍓佸殠閻ㄥ嫭妞傞崐娆掔箲閸ョ偠绐涚粋姹団偓浣虹帛閸掕泛顦挎潏鐟拌埌閵嗕礁娓鹃妴浣虹叐瑜般垺妞傞崐娆掔箲閸ョ偤娼扮粔顖ょ礉閸楁洑缍呮稉铏硅儗閿涳拷
     * <br />"<b>label</b>閿涙Label} 鐠侊紕鐣婚棃銏⑿濋弮璺衡偓娆忓毉閻滄澘婀狹ap娑撳﹦娈慙abel鐎电钖
     *
     * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b>
     * myDrawingManagerObject.addEventListener("overlaycomplete", function(e) {
     *     alert(e.drawingMode);
     *     alert(e.overlay);
     *     alert(e.calculate);
     *     alert(e.label);
     * });
     */

    /**
     * 缂佹ê鍩楅悙鐟扮暚閹存劕鎮楅敍灞炬烦閸欐垹娈戞禍瀣╂閹恒儱褰
     * @name DrawingManager#markercomplete
     * @event
     * @param {Marker} overlay 閸ョ偠鐨熼崙鑺ユ殶娴兼俺绻戦崶鐐垫祲鎼存梻娈戠憰鍡欐磰閻椻晪绱
     * <br />{"<b>overlay</b> : {Marker} 
     *
     * @example <b>閸欏倽鈧啰銇氭笟瀣剁窗</b>
     * myDrawingManagerObject.addEventListener("circlecomplete", function(e, overlay) {
     *     alert(overlay);
     * });
     */

    /**
     * 缂佹ê鍩楅崷鍡楃暚閹存劕鎮楅敍灞炬烦閸欐垹娈戞禍瀣╂閹恒儱褰
     * @name DrawingManager#circlecomplete
     * @event
     * @param {Circle} overlay 閸ョ偠鐨熼崙鑺ユ殶娴兼俺绻戦崶鐐垫祲鎼存梻娈戠憰鍡欐磰閻椻晪绱
     * <br />{"<b>overlay</b> : {Circle} 
     */

    /**
     * 缂佹ê鍩楃痪鍨暚閹存劕鎮楅敍灞炬烦閸欐垹娈戞禍瀣╂閹恒儱褰
     * @name DrawingManager#polylinecomplete
     * @event
     * @param {Polyline} overlay 閸ョ偠鐨熼崙鑺ユ殶娴兼俺绻戦崶鐐垫祲鎼存梻娈戠憰鍡欐磰閻椻晪绱
     * <br />{"<b>overlay</b> : {Polyline} 
     */

    /**
     * 缂佹ê鍩楁径姘崇珶瑜般垹鐣幋鎰倵閿涘本娣抽崣鎴犳畱娴滃娆㈤幒銉ュ經
     * @name DrawingManager#polygoncomplete
     * @event
     * @param {Polygon} overlay 閸ョ偠鐨熼崙鑺ユ殶娴兼俺绻戦崶鐐垫祲鎼存梻娈戠憰鍡欐磰閻椻晪绱
     * <br />{"<b>overlay</b> : {Polygon} 
     */

    /**
     * 缂佹ê鍩楅惌鈺佽埌鐎瑰本鍨氶崥搴礉濞叉儳褰傞惃鍕皑娴犺埖甯撮崣锟
     * @name DrawingManager#rectanglecomplete
     * @event
     * @param {Polygon} overlay 閸ョ偠鐨熼崙鑺ユ殶娴兼俺绻戦崶鐐垫祲鎼存梻娈戠憰鍡欐磰閻椻晪绱
     * <br />{"<b>overlay</b> : {Polygon} 
     */

    /**
     * 閸掓繂顫愰崠鏍Ц閹拷
     * @param {Map} 閸︽澘娴樼圭偘绶
     * @param {Object} 閸欏倹鏆
     */
    DrawingManager.prototype._initialize = function(map, opts) {

        /**
         * map鐎电钖
         * @private
         * @type {Map}
         */
        this._map = map;

        /**
         * 闁板秶鐤嗙电钖
         * @private
         * @type {Object}
         */
        this._opts = opts;

        /**
         * 瑜版挸澧犻惃鍕帛閸掕埖膩瀵拷, 姒涙ǹ顓婚弰顖滅帛閸掑墎鍋
         * @private
         * @type {DrawingType}
         */
        this._drawingType = opts.drawingMode || BMAP_DRAWING_MARKER;

        /**
         * 閺勵垰鎯佸ǎ璇插濞ｈ濮炴Η鐘崇垼缂佹ê鍩楀銉ュ徔閺嶅繘娼伴弶锟
         */
        if (opts.enableDrawingTool) {
            var drawingTool  = new DrawingTool(this, opts.drawingToolOptions);
            this._drawingTool = drawingTool;
            map.addControl(drawingTool);
        }

        //閺勵垰鎯佺拋锛勭暬缂佹ê鍩楅崙铏规畱闂堛垻袧 
        if (opts.enableCalculate === true) {
            this.enableCalculate();
        } else {
            this.disableCalculate();
        }

        /**
         * 閺勵垰鎯佸鑼病瀵偓閸氼垯绨＄紒妯哄煑閻樿埖鈧拷
         * @private
         * @type {Boolean}
         */
        this._isOpen = !!(opts.isOpen === true);
        if (this._isOpen) {
            this._open();
        }

        this.markerOptions    = opts.markerOptions    || {};
        this.circleOptions    = opts.circleOptions    || {};
        this.polylineOptions  = opts.polylineOptions  || {};
        this.polygonOptions   = opts.polygonOptions   || {};
        this.rectangleOptions = opts.rectangleOptions || {};
        this.controlButton =  opts.controlButton == "right" ? "right" : "left";

    },

    /**
     * 瀵偓閸氼垰婀撮崶鍓ф畱缂佹ê鍩楅悩鑸碘偓锟
     * @return {Boolean}閿涘苯绱戦崥顖滅帛閸掑墎濮搁幀浣瑰灇閸旂噦绱濇潻鏂挎礀true閿涙稑鎯侀崚娆掔箲閸ョ巃lse閵嗭拷
     */
    DrawingManager.prototype._open = function() {

        this._isOpen = true;

        //濞ｈ濮為柆顔惧兊閿涘本澧嶉張澶愮炊閺嶅洦鎼锋担婊堝厴閸︺劏绻栨稉顏堜紕缂冣晙绗傜瑰本鍨
        if (!this._mask) {
            this._mask = new Mask();
        }
        this._map.addOverlay(this._mask);
        this._setDrawingMode(this._drawingType);

    }

    /**
     * 鐠佸墽鐤嗚ぐ鎾冲閻ㄥ嫮绮崚鑸的佸锟
     * @param {DrawingType}
     */
    DrawingManager.prototype._setDrawingMode = function(drawingType) {

        this._drawingType = drawingType;

        /**
         * 瀵偓閸氼垳绱潏鎴犲Ц閹焦妞傞崐娆愬闁插秵鏌婃潻娑滎攽娴滃娆㈢紒鎴濈暰
         */
        if (this._isOpen) {

            //濞撳懐鈹栨稊瀣閻ㄥ嫯鍤滅规矮绠熸禍瀣╂
            this._mask.__listeners = {};

            switch (drawingType) {
                case BMAP_DRAWING_MARKER:
                    this._bindMarker();
                    break;
                case BMAP_DRAWING_CIRCLE:
                    this._bindCircle();
                    break;
                case BMAP_DRAWING_POLYLINE:
                case BMAP_DRAWING_POLYGON:
                    this._bindPolylineOrPolygon();
                    break;
                case BMAP_DRAWING_RECTANGLE:
                    this._bindRectangle();
                    break;
            }
        }

        /** 
         * 婵″倹鐏夊ǎ璇插娴滃棗浼愰崗閿嬬埉閿涘苯鍨稊鐔兼付鐟曚焦鏁奸崣妯轰紣閸忛攱鐖惃鍕壉瀵拷
         */
        if (this._drawingTool && this._isOpen) {
            this._drawingTool.setStyleByDrawingMode(drawingType);
        }
    }

    /**
     * 閸忔娊妫撮崷鏉挎禈閻ㄥ嫮绮崚鍓佸Ц閹拷
     * @return {Boolean}閿涘苯鍙ч梻顓犵帛閸掑墎濮搁幀浣瑰灇閸旂噦绱濇潻鏂挎礀true閿涙稑鎯侀崚娆掔箲閸ョ巃lse閵嗭拷
     */
    DrawingManager.prototype._close = function() {

        this._isOpen = false;


        if (this._mask) {
            this._map.removeOverlay(this._mask);
        }

        /** 
         * 婵″倹鐏夊ǎ璇插娴滃棗浼愰崗閿嬬埉閿涘苯鍨崗鎶芥４閺冭泛鈧瑥鐨㈠銉ュ徔閺嶅繑鐗卞蹇氼啎缂冾喕璐熼幏鏍ㄥ閸︽澘娴
         */
        if (this._drawingTool) {
            this._drawingTool.setStyleByDrawingMode("hander");
        }
    }

    /**
     * 缂佹垵鐣炬Η鐘崇垼閻㈣崵鍋ｉ惃鍕皑娴狅拷
     */
    DrawingManager.prototype._bindMarker = function() {

        var me   = this,
            map  = this._map,
            mask = this._mask;

        /**
         * 姒х姵鐖ｉ悙鐟板毊閻ㄥ嫪绨ㄦ禒锟
         */
        var clickAction = function (e) {
            // 瀵扳偓閸︽澘娴樻稉濠冨潑閸旂垑arker
            var marker = new BMap.Marker(e.point, me.markerOptions);
            map.addOverlay(marker);
            me._dispatchOverlayComplete(marker);
        }

        mask.addEventListener('click', clickAction);
    }

    /**
     * 缂佹垵鐣炬Η鐘崇垼閻㈣娓鹃惃鍕皑娴狅拷
     */
    DrawingManager.prototype._bindCircle = function() {

        var me           = this,
            map          = this._map,
            mask         = this._mask,
            circle       = null,
            centerPoint  = null; //閸﹀棛娈戞稉顓炵妇閻愶拷

        /**
         * 瀵偓婵绮崚璺烘妇瑜帮拷
         */
        var startAction = function (e) {
            if(me.controlButton == "right" && (e.button == 1 || e.button==0)){
                return ;
            }
            centerPoint = e.point;
            circle = new BMap.Circle(centerPoint, 0, me.circleOptions);
            map.addOverlay(circle);
            mask.enableEdgeMove();
            mask.addEventListener('mousemove', moveAction);
            baidu.on(document, 'mouseup', endAction);
        }

        /**
         * 缂佹ê鍩楅崷鍡楄埌鏉╁洨鈻兼稉顓ㄧ礉姒х姵鐖ｇ粔璇插З鏉╁洨鈻奸惃鍕皑娴狅拷
         */
        var moveAction = function(e) {
            circle.setRadius(me._map.getDistance(centerPoint, e.point));
        }

        /**
         * 缂佹ê鍩楅崷鍡楄埌缂佹挻娼
         */
        var endAction = function (e) {
            var calculate = me._calculate(circle, e.point);
            me._dispatchOverlayComplete(circle, calculate);
            centerPoint = null;
            mask.disableEdgeMove();
            mask.removeEventListener('mousemove', moveAction);
            baidu.un(document, 'mouseup', endAction);
        }

        /**
         * 姒х姵鐖ｉ悙鐟板毊鐠у嘲顫愰悙锟
         */
        var mousedownAction = function (e) {
            baidu.preventDefault(e);
            baidu.stopBubble(e);
            if(me.controlButton == "right" && e.button == 1){
                return ;
            }
            if (centerPoint == null) {
                startAction(e);
            } 
        }

        mask.addEventListener('mousedown', mousedownAction);
    }

    /**
     * 閻㈣崵鍤庨崪宀鏁炬径姘崇珶瑜般垻娴夋导鍏尖偓褎鐦潏鍐ㄣ亣閿涘苯鍙曢悽銊ょ娑擃亝鏌熷▔锟
     */
    DrawingManager.prototype._bindPolylineOrPolygon = function() {

        var me           = this,
            map          = this._map,
            mask         = this._mask,
            points       = [],   //閻€劍鍩涚紒妯哄煑閻ㄥ嫮鍋
            drawPoint    = null; //鐎圭偤妾棁鈧憰浣烘暰閸︺劌婀撮崶鍙ョ瑐閻ㄥ嫮鍋
            overlay      = null,
            isBinded     = false;

        /**
         * 姒х姵鐖ｉ悙鐟板毊閻ㄥ嫪绨ㄦ禒锟
         */
        var startAction = function (e) {
            if(me.controlButton == "right" && (e.button == 1 || e.button==0)){
                return ;
            }
            points.push(e.point);
            drawPoint = points.concat(points[points.length - 1]);
            if (points.length == 1) {
                if (me._drawingType == BMAP_DRAWING_POLYLINE) {

                    overlay = new BMap.Polyline(drawPoint, me.polylineOptions);
                } else if (me._drawingType == BMAP_DRAWING_POLYGON) {
                    overlay = new BMap.Polygon(drawPoint, me.polygonOptions);
                }
                map.addOverlay(overlay);
            } else {
                overlay.setPath(drawPoint);
            }
            if (!isBinded) {
                isBinded = true;
                mask.enableEdgeMove();
                mask.addEventListener('mousemove', mousemoveAction);
                mask.addEventListener('dblclick', dblclickAction);
            }
        }

        /**
         * 姒х姵鐖ｇ粔璇插З鏉╁洨鈻奸惃鍕皑娴狅拷
         */
        var mousemoveAction = function(e) {
            overlay.setPositionAt(drawPoint.length - 1, e.point);
        }

        /**
         * 姒х姵鐖ｉ崣灞藉毊閻ㄥ嫪绨ㄦ禒锟
         */
        var dblclickAction = function (e) {
            baidu.stopBubble(e);
            isBinded = false;
            mask.disableEdgeMove();
            mask.removeEventListener('mousedown',startAction);
            mask.removeEventListener('mousemove', mousemoveAction);
            mask.removeEventListener('dblclick', dblclickAction);
            //console.log(me.controlButton);
            if(me.controlButton == "right"){
                points.push(e.point);
            }
            else if(baidu.ie <= 8){
            }else{
                points.pop();
            }
            //console.log(points.length);
            overlay.setPath(points);
            var calculate = me._calculate(overlay, points.pop());
            me._dispatchOverlayComplete(overlay, calculate);
            points.length = 0;
            drawPoint.length = 0;
            me.close();

        }
        
        mask.addEventListener('mousedown', startAction);

        //閸欏苯鍤弮璺衡偓娆庣瑝閺鎯с亣閸︽澘娴樼痪褍鍩
        mask.addEventListener('dblclick', function(e){
            baidu.stopBubble(e);
        });
    }

    /**
     * 缂佹垵鐣炬Η鐘崇垼閻㈣崵鐓╄ぐ銏㈡畱娴滃娆
     */
    DrawingManager.prototype._bindRectangle = function() {

        var me           = this,
            map          = this._map,
            mask         = this._mask,
            polygon      = null,
            startPoint   = null;

        /**
         * 瀵偓婵绮崚鍓佺叐瑜帮拷
         */
        var startAction = function (e) {
            baidu.stopBubble(e);
            baidu.preventDefault(e);
            if(me.controlButton == "right" && (e.button == 1 || e.button==0)){
                return ;
            }
            startPoint = e.point;
            var endPoint = startPoint;
            polygon = new BMap.Polygon(me._getRectanglePoint(startPoint, endPoint), me.rectangleOptions);
            map.addOverlay(polygon);
            mask.enableEdgeMove();
            mask.addEventListener('mousemove', moveAction);
            baidu.on(document, 'mouseup', endAction);
        }

        /**
         * 缂佹ê鍩楅惌鈺佽埌鏉╁洨鈻兼稉顓ㄧ礉姒х姵鐖ｇ粔璇插З鏉╁洨鈻奸惃鍕皑娴狅拷
         */
        var moveAction = function(e) {
            polygon.setPath(me._getRectanglePoint(startPoint, e.point));
        }

        /**
         * 缂佹ê鍩楅惌鈺佽埌缂佹挻娼
         */
        var endAction = function (e) {
            var calculate = me._calculate(polygon, polygon.getPath()[2]);
            me._dispatchOverlayComplete(polygon, calculate);
            startPoint = null;
            mask.disableEdgeMove();
            mask.removeEventListener('mousemove', moveAction);
            baidu.un(document, 'mouseup', endAction);
        }

        mask.addEventListener('mousedown', startAction);
    }

    /**
     * 濞ｈ濮為弰鍓с仛閹碘偓缂佹ê鍩楅崶鎯ц埌閻ㄥ嫰娼扮粔顖涘灗閼板懘鏆辨惔锟
     * @param {overlay} 鐟曞棛娲婇悧锟
     * @param {point} 閺勫墽銇氶惃鍕秴缂冿拷
     */
    DrawingManager.prototype._calculate = function (overlay, point) {
        var result = {
            data  : 0,    //鐠侊紕鐣婚崙鐑樻降閻ㄥ嫰鏆辨惔锔藉灗闂堛垻袧
            label : null  //閺勫墽銇氶梹鍨閹存牠娼扮粔顖滄畱label鐎电钖
        };
        if (this._enableCalculate && BMapLib.GeoUtils) {
            var type = overlay.toString();
            //娑撳秴鎮撶憰鍡欐磰閻椻晞鐨熼悽銊ょ瑝閸氬瞼娈戠拋锛勭暬閺傝纭
            switch (type) {
                case "[object Polyline]":
                    result.data = BMapLib.GeoUtils.getPolylineDistance(overlay);
                    break;
                case "[object Polygon]":
                    result.data = BMapLib.GeoUtils.getPolygonArea(overlay);
                    break;
                case "[object Circle]":
                    var radius = overlay.getRadius();
                    result.data = Math.PI * radius * radius;
                    break;
            }
            //娑撯偓閸︾儤鍎忛崘闈涱槱閻烇拷
            if (!result.data || result.data < 0) {
                result.data = 0;
            } else {
                //娣囨繄鏆2娴ｅ秴鐨弫棰佺秴
                result.data = result.data.toFixed(2);
            }
            result.label = this._addLabel(point, result.data);
        }
        return result;
    }

    /**
     * 瀵偓閸氼垱绁寸捄婵嗘嫲濞村娼伴崝鐔诲厴闂団偓鐟曚椒绶风挧鏍︾艾GeoUtils鎼达拷
     * 閹碘偓娴犮儴绻栭柌灞藉灲閺傤厾鏁ら幋閿嬫Ц閸氾箑鍑＄紒蹇撳鏉烇拷,閼汇儲婀崝鐘烘祰閸掓瑧鏁s閸斻劍鈧礁濮炴潪锟
     */
    DrawingManager.prototype._addGeoUtilsLibrary = function () {
        if (!BMapLib.GeoUtils) {
            var script = document.createElement('script');
            script.setAttribute("type", "text/javascript");
            script.setAttribute("src", 'http://api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils_min.js');
            document.body.appendChild(script);
        }
    }

    /**
     * 閸氭垵婀撮崶鍙ヨ厬濞ｈ濮為弬鍥ㄦ拱閺嶅洦鏁
     * @param {Point}
     * @param {String} 閹碘偓娴犮儲妯夌粈铏规畱閸愬懎顔
     */
    DrawingManager.prototype._addLabel = function (point, content) {
        var label = new BMap.Label(content, {
            position: point
        });
        this._map.addOverlay(label);
        return label;
    }

    /**
     * 閺嶈宓佺挧椋庣矒閻愮骞忛崣鏍叐瑜般垻娈戦崶娑楅嚋妞ゅ墎鍋
     * @param {Point} 鐠ч鍋
     * @param {Point} 缂佸牏鍋
     */
    DrawingManager.prototype._getRectanglePoint = function (startPoint, endPoint) {
        return [
            new BMap.Point(startPoint.lng,startPoint.lat),
            new BMap.Point(endPoint.lng,startPoint.lat),
            new BMap.Point(endPoint.lng,endPoint.lat),
            new BMap.Point(startPoint.lng,endPoint.lat)
        ];
    }

    /**
     * 濞叉儳褰傛禍瀣╂
     */
    DrawingManager.prototype._dispatchOverlayComplete = function (overlay, calculate) {
        var options = {
            'overlay'     : overlay,
            'drawingMode' : this._drawingType
        };
        if (calculate) {
            options.calculate = calculate.data || null;
            options.label = calculate.label || null;
        }
        this.dispatchEvent(this._drawingType + 'complete', overlay);
        this.dispatchEvent('overlaycomplete', options);
    }

    /**
     * 閸掓稑缂撻柆顔惧兊鐎电钖
     */
    function Mask(){
        /**
         * 姒х姵鐖ｉ崚鏉挎勾閸ユ崘绔熺紓妯兼畱閺冭泛鈧瑦妲搁崥锕佸殰閸斻劌閽╃粔璇叉勾閸ワ拷
         */
        this._enableEdgeMove = false;
    }

    Mask.prototype = new BMap.Overlay();

    /**
     * 鏉╂瑩鍣锋稉宥勫▏閻⑩暆pi娑擃厾娈戦懛顏勭暰娑斿绨ㄦ禒璁圭礉閺勵垯璐熸禍鍡樻纯閻忓灚妞挎担璺ㄦ暏
     */
    Mask.prototype.dispatchEvent = baidu.lang.Class.prototype.dispatchEvent;
    Mask.prototype.addEventListener = baidu.lang.Class.prototype.addEventListener;
    Mask.prototype.removeEventListener = baidu.lang.Class.prototype.removeEventListener;

    Mask.prototype.initialize = function(map){
        var me = this;
        this._map = map;
        var div = this.container = document.createElement("div");
        var size = this._map.getSize();
        div.style.cssText = "position:absolute;background:url(about:blank);cursor:crosshair;width:" + size.width + "px;height:" + size.height + "px";
        this._map.addEventListener('resize', function(e) {
            me._adjustSize(e.size);
        });
        this._map.getPanes().floatPane.appendChild(div);
        this._bind();
        return div; 
    };

    Mask.prototype.draw = function() {
        var map   = this._map,
            point = map.pixelToPoint(new BMap.Pixel(0, 0)),
            pixel = map.pointToOverlayPixel(point);
        this.container.style.left = pixel.x + "px";
        this.container.style.top  = pixel.y + "px"; 
    };

    /**
     * 瀵偓閸氼垶绱堕弽鍥у煂閸︽澘娴樻潏鍦喘閿涘矁鍤滈崝銊ラ挬缁夎婀撮崶锟
     */
    Mask.prototype.enableEdgeMove = function() {
        this._enableEdgeMove = true;
    }

    /**
     * 閸忔娊妫存Η鐘崇垼閸掓澘婀撮崶鎹愮珶缂傛﹫绱濋懛顏勫З楠炲磭些閸︽澘娴
     */
    Mask.prototype.disableEdgeMove = function() {
        clearInterval(this._edgeMoveTimer);
        this._enableEdgeMove = false;
    }

    /**
     * 缂佹垵鐣炬禍瀣╂,濞叉儳褰傞懛顏勭暰娑斿绨ㄦ禒锟
     */
    Mask.prototype._bind = function() {

        var me = this,
            map = this._map,
            container = this.container,
            lastMousedownXY = null,
            lastClickXY = null;

        /**
         * 閺嶈宓乪vent鐎电钖勯懢宄板絿姒х姵鐖ｉ惃鍓巠閸ф劖鐖ｇ电钖
         * @param {Event}
         * @return {Object} {x:e.x, y:e.y}
         */
        var getXYbyEvent = function(e){
            return {
                x : e.clientX,
                y : e.clientY
            }
        };

        var domEvent = function(e) {
            var type = e.type;
                e = baidu.getEvent(e);
                point = me.getDrawPoint(e); //瑜版挸澧犳Η鐘崇垼閹碘偓閸︺劎鍋ｉ惃鍕勾閻炲棗娼楅弽锟

            var dispatchEvent = function(type) {
                e.point = point;
                me.dispatchEvent(e);
            }

            if (type == "mousedown") {
                lastMousedownXY = getXYbyEvent(e);
            }

            var nowXY = getXYbyEvent(e);
            //click缂佸繗绻冩稉鈧禍娑氬濞堝﹤顦╅悶鍡樻烦閸欐埊绱濋崗鏈电铂閸氬奔绨ㄦ禒鑸靛瘻濮濓絽鐖堕惃鍒m娴滃娆㈠ú鎯у絺
            if (type == "click") {
                //姒х姵鐖ｉ悙鐟板毊鏉╁洨鈻兼稉宥堢箻鐞涘瞼些閸斻劍澧犲ú鎯у絺click閸滃畳blclick
                if (Math.abs(nowXY.x - lastMousedownXY.x) < 5 && Math.abs(nowXY.y - lastMousedownXY.y) < 5 ) {
                    if (!lastClickXY || !(Math.abs(nowXY.x - lastClickXY.x) < 5 && Math.abs(nowXY.y - lastClickXY.y) < 5)) {
                        dispatchEvent('click');
                        lastClickXY = getXYbyEvent(e);
                    } else {
                        lastClickXY = null;
                    }
                }
            } else {
                dispatchEvent(type);
            }
        }

        /**
         * 鐏忓棔绨ㄦ禒鍫曞厴闁喚鍍电仦鍌滄畱娴滃娆㈤柈鐣岀拨鐎规艾鍩宒omEvent閺夈儱顦╅悶锟
         */
        var events = ['click', 'mousedown', 'mousemove', 'mouseup', 'dblclick'],
            index = events.length;
        while (index--) {
            baidu.on(container, events[index], domEvent);
        }

        //姒х姵鐖ｇ粔璇插З鏉╁洨鈻兼稉顓ㄧ礉閸掓澘婀撮崶鎹愮珶缂傛ê鎮楅懛顏勫З楠炲磭些閸︽澘娴
        baidu.on(container, 'mousemove', function(e) {
            if (me._enableEdgeMove) {
                me.mousemoveAction(e);
            }
        });
    };

    //姒х姵鐖ｇ粔璇插З鏉╁洨鈻兼稉顓ㄧ礉閸掓澘婀撮崶鎹愮珶缂傛ê鎮楅懛顏勫З楠炲磭些閸︽澘娴
    Mask.prototype.mousemoveAction = function(e) {
        function getClientPosition(e) {
            var clientX = e.clientX,
                clientY = e.clientY;
            if (e.changedTouches) {
                clientX = e.changedTouches[0].clientX;
                clientY = e.changedTouches[0].clientY;
            }
            return new BMap.Pixel(clientX, clientY);
        }

        var map       = this._map,
            me        = this,
            pixel     = map.pointToPixel(this.getDrawPoint(e)),
            clientPos = getClientPosition(e),
            offsetX   = clientPos.x - pixel.x,
            offsetY   = clientPos.y - pixel.y;
        pixel = new BMap.Pixel((clientPos.x - offsetX), (clientPos.y - offsetY));
        this._draggingMovePixel = pixel;
        var point = map.pixelToPoint(pixel),
            eventObj = {
                pixel: pixel,
                point: point
            };
        // 閹锋牗瀚块崚鏉挎勾閸ユ崘绔熺紓妯夹╅崝銊ユ勾閸ワ拷
        this._panByX = this._panByY = 0;
        if (pixel.x <= 20 || pixel.x >= map.width - 20
            || pixel.y <= 50 || pixel.y >= map.height - 10) {
            if (pixel.x <= 20) {
                this._panByX = 8;
            } else if (pixel.x >= map.width - 20) {
                this._panByX = -8;
            }
            if (pixel.y <= 50) {
                this._panByY = 8;
            } else if (pixel.y >= map.height - 10) {
                this._panByY = -8;
            }
            if (!this._edgeMoveTimer) {
                this._edgeMoveTimer = setInterval(function(){
                    map.panBy(me._panByX, me._panByY, {"noAnimation": true});
                }, 30);
            }
        } else {
            if (this._edgeMoveTimer) {
                clearInterval(this._edgeMoveTimer);
                this._edgeMoveTimer = null;
            }
        }
    }

    /*
     * 鐠嬪啯鏆ｆ径褍鐨
     * @param {Size}
     */
    Mask.prototype._adjustSize = function(size) {
        this.container.style.width  = size.width + 'px';
        this.container.style.height = size.height + 'px';
    };

    /**
     * 閼惧嘲褰囪ぐ鎾冲缂佹ê鍩楅悙鍦畱閸︽壆鎮婇崸鎰垼
     *
     * @param {Event} e e鐎电钖
     * @return Point鐎电钖勯惃鍕秴缂冾喕淇婇幁锟
     */
    Mask.prototype.getDrawPoint = function(e) {
        
        var map = this._map,
        trigger = baidu.getTarget(e),
        x = e.offsetX || e.layerX || 0,
        y = e.offsetY || e.layerY || 0;
        if (trigger.nodeType != 1) trigger = trigger.parentNode;
        while (trigger && trigger != map.getContainer()) {
            if (!(trigger.clientWidth == 0 &&
                trigger.clientHeight == 0 &&
                trigger.offsetParent && trigger.offsetParent.nodeName == 'TD')) {
                x += trigger.offsetLeft || 0;
                y += trigger.offsetTop || 0;
            }
            trigger = trigger.offsetParent;
        }
        var pixel = new BMap.Pixel(x, y);
        var point = map.pixelToPoint(pixel);
        return point;

    }

    /**
     * 缂佹ê鍩楀銉ュ徔闂堛垺婢橀敍宀冨殰鐎规矮绠熼幒褌娆
     */
    function DrawingTool(drawingManager, drawingToolOptions) {
        this.drawingManager = drawingManager;

        drawingToolOptions = this.drawingToolOptions = drawingToolOptions || {};
        // 姒涙ǹ顓婚崑婊堟浆娴ｅ秶鐤嗛崪灞戒焊缁夊鍣
        this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT;
        this.defaultOffset = new BMap.Size(10, 10);

        //姒涙ǹ顓婚幍鈧張澶婁紣閸忛攱鐖柈鑺ユ▔缁锟
        this.defaultDrawingModes = [
            BMAP_DRAWING_MARKER,
            BMAP_DRAWING_CIRCLE,
            BMAP_DRAWING_POLYLINE,
            BMAP_DRAWING_POLYGON,
            BMAP_DRAWING_RECTANGLE
        ];
        //瀹搞儱鍙块弽蹇撳讲閺勫墽銇氶惃鍕帛閸掕埖膩瀵拷
        if (drawingToolOptions.drawingModes) {
            this.drawingModes = drawingToolOptions.drawingModes;
        } else {
            this.drawingModes = this.defaultDrawingModes
        }

        //閻€劍鍩涚拋鍓х枂閸嬫粓娼担宥囩枂閸滃苯浜哥粔濠氬櫤
        if (drawingToolOptions.anchor) {
            this.setAnchor(drawingToolOptions.anchor);
        }
        if (drawingToolOptions.offset) {
            this.setOffset(drawingToolOptions.offset);
        }
    }

    // 闁俺绻僇avaScript閻ㄥ埦rototype鐏炵偞鈧呮埛閹靛じ绨珺Map.Control
    DrawingTool.prototype = new BMap.Control();

    // 閼奉亜鐣炬稊澶嬪付娴犺泛绻妞よ鐤勯悳鎷屽殰瀹歌京娈慽nitialize閺傝纭,楠炴湹绗栫亸鍡樺付娴犲墎娈慏OM閸忓啰绀屾潻鏂挎礀
    // 閸︺劍婀伴弬瑙勭《娑擃厼鍨卞杞伴嚋div閸忓啰绀屾担婊璐熼幒褌娆㈤惃鍕啇閸ｏ拷,楠炶泛鐨㈤崗鑸靛潑閸旂姴鍩岄崷鏉挎禈鐎圭懓娅掓稉锟
    DrawingTool.prototype.initialize = function(map){
        // 閸掓稑缂撴稉鈧稉鐙M閸忓啰绀
        var container = this.container = document.createElement("div");
        container.className = "BMapLib_Drawing";
        //閻€劍娼电拋鍓х枂婢舵牕鐪版潏瑙勵攱闂冩潙濂
        var panel = this.panel = document.createElement("div");
        panel.className = "BMapLib_Drawing_panel";
        if (this.drawingToolOptions && this.drawingToolOptions.scale) {
            this._setScale(this.drawingToolOptions.scale);
        }
        container.appendChild(panel);
        // 濞ｈ濮為崘鍛啇
        panel.innerHTML = this._generalHtml();
        //缂佹垵鐣炬禍瀣╂
        this._bind(panel);
        // 濞ｈ濮濪OM閸忓啰绀岄崚鏉挎勾閸ュ彞鑵
        map.getContainer().appendChild(container);
        // 鐏忓挷OM閸忓啰绀屾潻鏂挎礀
        return container;
    }

    //閻㈢喐鍨氬銉ュ徔閺嶅繒娈慼tml閸忓啰绀
    DrawingTool.prototype._generalHtml = function(map){

        //姒х姵鐖ｇ紒蹇氱箖瀹搞儱鍙块弽蹇庣瑐閻ㄥ嫭褰佺粈杞颁繆閹拷
        var tips = {};
        tips["hander"]               = "";
        tips[BMAP_DRAWING_MARKER]    = "";
        tips[BMAP_DRAWING_CIRCLE]    = "鍦嗗舰";
        tips[BMAP_DRAWING_POLYLINE]  = "璺嚎";
        tips[BMAP_DRAWING_POLYGON]   = "澶氳竟褰";
        tips[BMAP_DRAWING_RECTANGLE] = "鐭╁舰";

        var getItem = function(className, drawingType) {
            return '<a class="' + className + '" drawingType="' + drawingType + '" href="javascript:void(0)" title="' + tips[drawingType] + '" onfocus="this.blur()"></a>';
        }

        var html = [];
        html.push(getItem("BMapLib_box BMapLib_hander", "hander"));
        for (var i = 0, len = this.drawingModes.length; i < len; i++) {
            var classStr = 'BMapLib_box BMapLib_' + this.drawingModes[i];
            if (i == len-1) {
                classStr += ' BMapLib_last';
            }
            html.push(getItem(classStr, this.drawingModes[i]));
        }
        return html.join('');
    }

    /**
     * 鐠佸墽鐤嗗銉ュ徔閺嶅繒娈戠紓鈺傛杹濮ｆ柧绶
     */
    DrawingTool.prototype._setScale = function(scale){
        var width  = 390,
            height = 50,
            ml = -parseInt((width - width * scale) / 2, 10),
            mt = -parseInt((height - height * scale) / 2, 10);
        this.container.style.cssText = [
            "-moz-transform: scale(" + scale + ");",
            "-o-transform: scale(" + scale + ");",
            "-webkit-transform: scale(" + scale + ");",
            "transform: scale(" + scale + ");",
            "margin-left:" + ml + "px;",
            "margin-top:" + mt + "px;",
            "*margin-left:0px;", //ie6閵嗭拷7
            "*margin-top:0px;",  //ie6閵嗭拷7
            "margin-left:0px\\0;", //ie8
            "margin-top:0px\\0;",  //ie8
            //ie娑撳濞囬悽銊︽姢闂锟
            "filter: progid:DXImageTransform.Microsoft.Matrix(",
            "M11=" + scale + ",",
            "M12=0,",
            "M21=0,",
            "M22=" + scale + ",",
            "SizingMethod='auto expand');"
        ].join('');
    }

    //缂佹垵鐣惧銉ュ徔閺嶅繒娈戞禍瀣╂
    DrawingTool.prototype._bind = function(panel){
        var me = this;
        baidu.on(this.panel, 'click', function (e) {
            var target = baidu.getTarget(e);
            var drawingType = target.getAttribute('drawingType');
            me.setStyleByDrawingMode(drawingType);
            me._bindEventByDraingMode(drawingType);
        });
    }

    //鐠佸墽鐤嗗銉ュ徔閺嶅繐缍嬮崜宥夆偓澶夎厬閻ㄥ嫰銆嶉弽宄扮础
    DrawingTool.prototype.setStyleByDrawingMode = function(drawingType){
        if (!drawingType) {
            return;
        }
        var boxs = this.panel.getElementsByTagName("a");
        for (var i = 0, len = boxs.length; i < len; i++) {
            var box = boxs[i];
            if (box.getAttribute('drawingType') == drawingType) {
                var classStr = "BMapLib_box BMapLib_" + drawingType + "_hover";
                if (i == len - 1) {
                    classStr += " BMapLib_last";
                }
                box.className = classStr;
            } else {
                box.className = box.className.replace(/_hover/, "");
            }
        }
    }

    //鐠佸墽鐤嗗銉ュ徔閺嶅繐缍嬮崜宥夆偓澶夎厬閻ㄥ嫰銆嶉弽宄扮础
    DrawingTool.prototype._bindEventByDraingMode = function(drawingType){
        var me = this;
        var drawingManager = this.drawingManager;
        //閻愮懓婀幏鏍ㄥ閸︽澘娴橀惃鍕瘻闁筋喕绗
        if (drawingType == "hander") {
            drawingManager.close();
            drawingManager._map.enableDoubleClickZoom();
        } else {
            drawingManager.setDrawingMode(drawingType);
            drawingManager.open();
            drawingManager._map.disableDoubleClickZoom();
        }
    }

    //閻€劍娼电涙ê鍋嶉悽銊﹀煕鐎圭偘绶ラ崠鏍у毉閺夈儳娈慸rawingmanager鐎电钖
    var instances = [];

    /*
     * 閸忔娊妫撮崗鏈电铂鐎圭偘绶ラ惃鍕帛閸掕埖膩瀵拷
     * @param {DrawingManager} 瑜版挸澧犻惃鍕杽娓氾拷
     */
    function closeInstanceExcept(instance) {
        var index = instances.length;
        while (index--) {
            if (instances[index] != instance) {
                instances[index].close();
            }
        }
    }

})();